﻿using Microsoft.Extensions.Caching.Distributed;

namespace PmSoft.Cache.Abstractions;

/// <summary>
/// 分布式内存缓存实现，用于实体缓存的分布式存储
/// </summary>
public class DistributedMemoryCache : ICache
{
	private readonly IDistributedCache _cache;

	/// <summary>
	/// 构造函数，初始化分布式缓存和序列化器
	/// </summary>
	/// <param name="distributedCache">分布式缓存实例</param>
	public DistributedMemoryCache(IDistributedCache distributedCache)
	{
		_cache = distributedCache ?? throw new ArgumentNullException(nameof(distributedCache));
	}

	/// <summary>
	/// 从分布式缓存获取实体（同步）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="key">缓存键</param>
	/// <returns>缓存的实体，若不存在则返回 null</returns>
	public T? Get<T>(string key)
	{
		if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key));
		return _cache.Get<T>(key.ToLower());
	}

	/// <summary>
	/// 从分布式缓存获取实体（异步）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="key">缓存键</param>
	/// <returns>缓存的实体，若不存在则返回 null</returns>
	public async Task<T?> GetAsync<T>(string key)
	{
		if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key));
		return await _cache.GetAsync<T>(key.ToLower());
	}

	/// <summary>
	/// 移除分布式缓存中的实体（同步）
	/// </summary>
	/// <param name="key">缓存键</param>
	public void Remove(string key)
	{
		if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key));
		_cache.Remove(key.ToLower());
	}

	/// <summary>
	/// 移除分布式缓存中的实体（异步）
	/// </summary>
	/// <param name="key">缓存键</param>
	public async Task RemoveAsync(string key)
	{
		if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key));
		await _cache.RemoveAsync(key.ToLower());
	}

	/// <summary>
	/// 设置分布式缓存中的实体（同步）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="key">缓存键</param>
	/// <param name="value">实体值</param>
	/// <param name="timeSpan">滑动过期时间</param>
	public void Set<T>(string key, T value, TimeSpan timeSpan)
	{
		if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key));
		if (value == null) throw new ArgumentNullException(nameof(value));
 
		_cache.Set(key.ToLower(), value, timeSpan);
	}

	/// <summary>
	/// 设置分布式缓存中的实体（异步）
	/// </summary>
	/// <typeparam name="T">实体类型</typeparam>
	/// <param name="key">缓存键</param>
	/// <param name="value">实体值</param>
	/// <param name="timeSpan">滑动过期时间</param>
	public async Task SetAsync<T>(string key, T value, TimeSpan timeSpan)
	{
		if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key));
		if (value == null) throw new ArgumentNullException(nameof(value));
 
		await _cache.SetAsync(key.ToLower(), value, timeSpan);
	}
}